package com.pig.easy.bpm.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.pig.easy.bpm.utils.SnowKeyGenUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * todo:
 *
 * @author : zhoulin.zhu
 * @date : 2019/7/23 11:08
 */

@Aspect
@Component
@Slf4j
public class MethodInterceptor {

    private static final String POINT = "execution (* com.pig.easy.bpm.service..*Impl.*(..))";

    @Value("${spring.profiles.active}")
    private String currentEvn;

    /**
     * 功能描述: 统计方法执行耗时Around环绕通知
     *
     * @param joinPoint
     * @return : java.lang.Object
     * @author : zhoulin.zhu
     * @date : 2019/7/23 11:28
     */
    @Around(POINT)
    public Object timeAround(ProceedingJoinPoint joinPoint) {

        Object result = null;
        long beginTime = System.currentTimeMillis();

        Object obj = null;
        Object[] args = joinPoint.getArgs();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        Set<Object> allParams = new LinkedHashSet<>();

        for (Object arg : args) {
            if (arg instanceof Map<?, ?>) {
                Map<String, Object> map = (Map<String, Object>) arg;
                allParams.add(map);
            } else {
                allParams.add(arg);
            }
        }

        String requestId = SnowKeyGenUtils.getInstance().getNextId();
        try {
            log.info("请求[{}]开始，方法：{}，参数：{}",requestId, methodName, JSONObject.toJSONString(allParams));
        } catch (Exception e) {
            log.info("请求[{}]开始，方法：{}，参数：{}",requestId, methodName, allParams);
        }

        try {
            result = joinPoint.proceed(args);
        } catch (Throwable e) {
            log.error("入参[{}]：{}，exception：{} ",requestId, JSONObject.toJSONString(allParams), e);
        }

        long costMs = System.currentTimeMillis() - beginTime;

        try {
            log.info("请求[{}]结束，方法：{}，耗时：{}ms，出参：{}",requestId, methodName, costMs, JSONObject.toJSONString(result));
        } catch (Exception e) {
            log.info("请求[{}]结束，方法：{}，耗时：{}ms，出参：{}",requestId, methodName, costMs, (result));
        }

        return result;
    }

}
